package com.intramirror.product.schedule.consumer;

import com.intramirror.common.entity.AIProductEntity;
import com.intramirror.product.entity.OrderLineSpuEntity;
import com.intramirror.product.entity.SuperiorProduct;
import com.intramirror.product.service.FacilityService;
import com.intramirror.product.utils.ConvertUtil;
import com.intramirror.utils.transform.JsonTransformUtil;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AISelectConsumer implements IProductConsumer {
    private static final Logger LOGGER = LoggerFactory.getLogger(AISelectConsumer.class);

    private static final int CREATE_ORDER_TYPE = 1;
    private static final int LACK_STOCK_TYPE = 2;
    private static final int ORDER_EXCEPTION_TYPE = 3;

    private FacilityService facilityService;

    AISelectConsumer(FacilityService facilityService) {
        this.facilityService = facilityService;
    }

    @Override
    public void process(String message) {

        AIProductEntity aiProductEntity = JsonTransformUtil.readValue(message, AIProductEntity.class);
        if (aiProductEntity == null) {
            LOGGER.warn("Received message transformed entity is null");
            return;
        }

        switch (aiProductEntity.getType()) {
        case CREATE_ORDER_TYPE:
        case ORDER_EXCEPTION_TYPE:
            processOrderWithOrderLine(aiProductEntity.getOrderLineNum(), aiProductEntity.getType());
            break;
        case LACK_STOCK_TYPE:
            processLackStock(aiProductEntity.getProductId(), aiProductEntity.getSkuId(), aiProductEntity.getType());
            break;
        }
    }

    private void processLackStock(Long productId, Long skuId, int type) {
        OrderLineSpuEntity orderLineSpuEntity = getSpuInfoByProductSku(productId, skuId);
        if (orderLineSpuEntity == null) {
            LOGGER.info("Could not find any superior product for product {}, skuId {}.", productId, skuId);
            return;
        }

        List<Map<String, Object>> aiSelectedList = getProductBySpuSku(orderLineSpuEntity);
        SuperiorProduct superiorProduct = getSuperiorProduct(aiSelectedList, orderLineSpuEntity);
        if (superiorProduct != null) {
            superiorProduct.setType(type);
            superiorProduct.setOrderLineNum("");
            LOGGER.info("Start to save superior product for product {}, skuId {}.", productId, skuId);
            facilityService.getProductService().saveSuperiorProduct(superiorProduct);
        }
    }

    private void processOrderWithOrderLine(String orderLineNum, int type) {
        OrderLineSpuEntity orderLineSpuEntity = getSpuByOrderLineNum(orderLineNum);
        if (orderLineSpuEntity == null) {
            LOGGER.info("Could not find any superior product for order line {}.", orderLineNum);
            return;
        }

        List<Map<String, Object>> aiSelectedList = getProductBySpuSku(orderLineSpuEntity);
        SuperiorProduct superiorProduct = getSuperiorProduct(aiSelectedList, orderLineSpuEntity);
        if (superiorProduct != null) {
            superiorProduct.setType(type);
            superiorProduct.setOrderLineNum(orderLineNum);
            LOGGER.info("Start to save superior product for product {}, skuId {}.", orderLineSpuEntity.getProductId(), orderLineSpuEntity.getSkuId());
            facilityService.getProductService().saveSuperiorProduct(superiorProduct);
        }
    }

    private OrderLineSpuEntity getSpuInfoByProductSku(Long productId, Long skuId) {
        OrderLineSpuEntity orderLineSpuEntity = facilityService.getProductService().getSpuByProductSku(skuId);
        if (orderLineSpuEntity == null) {
            LOGGER.info("Product {}, sku {}, not exists.", productId, skuId);
            return null;
        }

        if (orderLineSpuEntity.getSpuId() == null) {
            LOGGER.info("Product {}, sku {},  have no spu.", productId, skuId);
            return null;
        }
        return orderLineSpuEntity;
    }

    private OrderLineSpuEntity getSpuByOrderLineNum(String orderLineNum) {
        OrderLineSpuEntity orderLineSpuEntity = facilityService.getProductService().getSpuByOrderLineNum(orderLineNum);
        if (orderLineSpuEntity == null) {
            LOGGER.error("Could not find order line num {}.", orderLineNum);
            return null;
        }

        if (orderLineSpuEntity.getSpuId() == null) {
            LOGGER.info("The order line num {} with product {} sku {},  have no spu.", orderLineSpuEntity.getOrderLineNum(), orderLineSpuEntity.getProductId(),
                    orderLineSpuEntity.getSkuId());
            return null;
        }

        return orderLineSpuEntity;
    }

    private List<Map<String, Object>> getProductBySpuSku(OrderLineSpuEntity orderLineSpuEntity) {

        List<Map<String, Object>> result = facilityService.getProductService().getProductBySpuSku(orderLineSpuEntity);
        if (result == null) {
            return null;
        }
        return result;
    }

    private SuperiorProduct getSuperiorProduct(List<Map<String, Object>> aiSelectedList, OrderLineSpuEntity srcOrderSpuEntity) {
        SuperiorProduct superiorProduct = new SuperiorProduct();

        if (aiSelectedList != null && aiSelectedList.size() > 0) {
            Map<String, Object> aiSelected = aiSelectedList.get(0);

            if (ConvertUtil.toBigDecimal(aiSelected.get("boutique_price")).compareTo(srcOrderSpuEntity.getBoutiquePrice()) >= 0) {
                LOGGER.info("========>Superior product for product {}, sku {}, boutique price not win with {} >= {}.", srcOrderSpuEntity.getProductId(),
                        ConvertUtil.toBigDecimal(srcOrderSpuEntity.getSkuId()), aiSelected.get("boutique_price"), srcOrderSpuEntity.getBoutiquePrice());
                return null;
            }

            LOGGER.info("========>Find superior product for product {}, sku {}, boutique price {} < {}.", srcOrderSpuEntity.getProductId(),
                    ConvertUtil.toBigDecimal(srcOrderSpuEntity.getSkuId()), aiSelected.get("boutique_price"), srcOrderSpuEntity.getBoutiquePrice());

            superiorProduct.setTarProductId(ConvertUtil.toLong(aiSelected.get("product_id")));
            superiorProduct.setTarBrandId(ConvertUtil.toLong(aiSelected.get("brand_id")));
            superiorProduct.setTarVendorId(ConvertUtil.toLong(aiSelected.get("vendor_id")));
            superiorProduct.setTarCategoryId(ConvertUtil.toLong(aiSelected.get("category_id")));
            superiorProduct.setTarRetailPrice(ConvertUtil.toBigDecimal(aiSelected.get("retail_price")));
            superiorProduct.setTarBoutiquePrice(ConvertUtil.toBigDecimal(aiSelected.get("boutique_price")));
            superiorProduct.setTarImPrice(ConvertUtil.toBigDecimal(aiSelected.get("im_price")));
            superiorProduct.setTarSeasonCode(ConvertUtil.toString(aiSelected.get("season_code")));
            superiorProduct.setTarSpuId(ConvertUtil.toLong(aiSelected.get("spu_id")));
            superiorProduct.setTarProductCoverImg(ConvertUtil.toString(aiSelected.get("product_cover_img")));
            superiorProduct.setTarSpuCoverImg(ConvertUtil.toString(aiSelected.get("spu_cover_img")));
            superiorProduct.setTarStore(ConvertUtil.toInteger(aiSelected.get("store")));
            superiorProduct.setTarShopProductSkuId(ConvertUtil.toLong(aiSelected.get("shop_product_sku_id")));

            superiorProduct.setSrcVendorId(srcOrderSpuEntity.getVendorId());
            superiorProduct.setSrcBrandId(srcOrderSpuEntity.getBrandId());
            superiorProduct.setSrcCategoryId(srcOrderSpuEntity.getCategoryId());
            superiorProduct.setSrcProductId(srcOrderSpuEntity.getProductId());
            superiorProduct.setSrcSpuId(srcOrderSpuEntity.getSpuId());
            superiorProduct.setSrcSeasonCode(srcOrderSpuEntity.getSeasonCode());
            superiorProduct.setSrcProductCoverImg(srcOrderSpuEntity.getProductCoverImg());
            superiorProduct.setSrcSpuCoverImg(srcOrderSpuEntity.getSpuCoverImg());
            superiorProduct.setSrcStore(srcOrderSpuEntity.getStore());
            superiorProduct.setSrcShopProductSkuId(srcOrderSpuEntity.getShopProductSkuId());
            superiorProduct.setSrcImPrice(srcOrderSpuEntity.getImPrice());
            superiorProduct.setSrcBoutiquePrice(srcOrderSpuEntity.getBoutiquePrice());
            superiorProduct.setSrcRetailPrice(srcOrderSpuEntity.getRetailPrice());

            return superiorProduct;
        }
        return null;
    }
}
